package indi.lqzhi.component.picker;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorLong;
import androidx.annotation.IntRange;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import indi.lqzhi.component.R;

/**
 * https://blog.csdn.net/clg19780720/article/details/107159591
 */
public class ColorValuePicker extends View {

    private final static String TAG="ColorValuePicker";

    private final static int CENTER_CIRCLE_WIDTH=5;

    /**长按超过0.3秒，触发长按事件*/
    private static final int LONGPRESSTIME= 300;
    /**宽度*/
    private int width;
    /**高度*/
    private int height;
    /**圆环的宽*/
    private int RingWidth = 20;
    /**颜色选择器样式*/
    private PickerStyle colorPickerStyle=PickerStyle.MARK_RING_INNER;
    /**内圆的半径*/
    private float innerRadius;
    /**外圆的半径*/
    private float outerRadius;
    /**圆的圆心坐标*/
    private float circleX, circleY;
    /**圆环的画笔*/
    private Paint paintCircleRing;
    /**圆形选择器*/
    private Paint paintSelecter;
    /**圆形选择器填充色*/
    private int colorMarkFill =0xafffffff;
    /**圆形选择器描边画笔*/
    private Paint paintSelecterStroke;
    /**圆形选择器描边*/
    private boolean markStroke=false;
    /**圆形选择器描边颜色*/
    private int colorMarkStroke=0xff000000;
    /**选择器圆心坐标*/
    private float markPointX, markPointY;
    /**默认角度*/
    private float angle = 0;
    /**选择器自动色*/
    private boolean markAutoColor=true;
    /**扩散效果透明度*/
    private int spreadAlpha=128;
    /**选择器圆点边框宽度*/
    private int markStrokeWidth=1;
    /**色环颜色的发散位置*/
    private Shader shader;
    /**中间圆画笔，用于显示当前选中的颜色*/
    private Paint centerPaint;
    /**中心图片*/
    private Bitmap centerBitmap=null;
    /**着色器颜色*/
    private int tintColor=Color.BLACK;
    /**着色*/
    private boolean isTint=false;
    /**图片着色器列表*/
    private int[] tintArrayColor;
    /**中心图片透明度*/
    private int centerImageAlpha=255;
    /**中心圆半径*/
    private float centerRadius;
    /**中心按钮复选状态*/
    private boolean checked=false;
    /**当前点颜色*/
    private int currentColor;
    /**中心位图画刷*/
    private  Paint centerBitmapPaint;
    /**渐变色环参数：红、紫、蓝、青色、绿、黄、红*/
    private final int[] mCircleColors =new int[] {
            Color.RED ,
            Color.YELLOW ,
            Color.GREEN ,
            Color.CYAN ,
            Color.BLUE ,
            Color.MAGENTA ,
            Color.RED
    };
    /**冗长等级枚举*/
    public enum  PickerStyle{
        /**选择器在圆环内%*/
        MARK_RING_INNER(0),
        /**选择器超出圆环%*/
        MARK_RING_OUTER(1),
        /**选择器按下是超出圆环*/
        MARK_RING_DOWN_OUTER(2);
        private int style;
        /**选择器样式*/
        PickerStyle( int style){
            this.style=style;
        }
        /**获取选择器样式*/
        public int getStyle() {
            return this.style;
        }
    }
    /**在圆环上按下*/
    private boolean isRingDown=false;
    /**在选择器上按下*/
    private boolean isMarkPointRangeDown=false;
    /**用户改变*/
    private boolean isFromUser=false;
    /**中心按钮按下状态*/
    private boolean isButtonClick=false;
    /**上一次点击的的坐标*/
    private float lastX,lastY;
    /**计时器，计时点击时长*/
    private Timer timer;
    /**长按时间处理*/
    private TimerTask timerTaskLongDown;
    /**用于存放改变前的角度*/
    private float oleAngle=0;
    /**用于标识是否使用了长按*/
    private boolean isLongClick=false;
    /**
     * 当进颜色更改时通知客户端的回调。这包括用户通过触摸手势或箭头键/轨迹球发起的更改，以及以编程方式发起的更改。
     */
    public interface OnColorValuePickerChangeListener {
        /**
         * 改变通知。
         * 客户机可以使用from user参数将用户发起的更改与以编程方式发生的更改区分开来。
         * @param colorValuePicker 以改变的ColorValuePicker对象
         * @param angle 改变的角度值
         * @param fromUser 如果进度更改是由用户启动的，则为True。
         */
        void onChangeListener(ColorValuePicker colorValuePicker,float angle,boolean fromUser);
        /**
         * 通知用户已开始触摸手势。客户端可能希望使用此选项来禁用推进ColorValuePicker。
         * @param colorValuePicker 开始触摸手势的ColorValuePicker
         */
        void onStartTrackingTouch(ColorValuePicker colorValuePicker);

        /**
         * 通知用户已完成触摸手势。客户端可能希望使用此选项重新启用ColorValuePicker。
         * @param colorValuePicker 停止触摸手势的ColorValuePicker
         */
        void onStopTrackingTouch(ColorValuePicker colorValuePicker);
    }

    /**
     * 颜色选择器中心按钮的选中状态更改时要调用的回调的接口定义。
     */
    public interface OnCheckedChangeListener{
        /**
         * 当颜色选择器中心按钮的选中状态更改时调用。
         * @param colorPicker 状态已更改的颜色选择器视图。
         * @param isChecked 新选中状态。
         * @param fromUser 如果进度更改是由用户启动的，则为True。
         */
        void onCheckedChanged(ColorValuePicker colorPicker, boolean isChecked,boolean fromUser);
    }
    /**定义颜色选择器颜色选择更改通知变量*/
    private OnColorValuePickerChangeListener onColorValuePickerChangeListener;
    /**定义中心按钮状态改变通知变量*/
    private OnCheckedChangeListener onCheckedChangeListener;
    /**d定义中心按钮单击事件*/
    private OnClickListener onClickListener;
    /**定义中心按钮长按事件*/
    private OnLongClickListener onLongClickListener;
    /**
     * 构造函数
     * @param context 应用上下文
     */
    public ColorValuePicker(Context context) {
        this(context,null);
    }
    /**
     * 构造函数
     * @param context 应用上下文
     * @param attrs 控件属性集对象
     */
    public ColorValuePicker(Context context, @Nullable AttributeSet attrs) {
        this(context,attrs,0);
    }
    /**
     * 构造函数
     * @param context 应用上下文
     * @param attrs 控件属性集对象
     * @param defStyleAttr 默认样式
     */
    public ColorValuePicker(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.ColorValuePicker);
        this.angle=typedArray.getFloat(R.styleable.ColorValuePicker_angle,this.angle);
        this.colorMarkFill =typedArray.getColor(R.styleable.ColorValuePicker_markBackground,this.colorMarkFill );
        this.colorMarkStroke=typedArray.getColor(R.styleable.ColorValuePicker_markStrokeColor,this.colorMarkStroke);
        this.markStroke=typedArray.getBoolean(R.styleable.ColorValuePicker_isMarkStroke, this.markStroke);
        this.RingWidth=typedArray.getDimensionPixelOffset(R.styleable.ColorValuePicker_ringWidth,dp2px(context, this.RingWidth));
        this.markAutoColor=typedArray.getBoolean(R.styleable.ColorValuePicker_isMarkAutoColor,this.markAutoColor);
        this.spreadAlpha=typedArray.getInt(R.styleable.ColorValuePicker_spreadAlpha,this.spreadAlpha);
        this.markStrokeWidth=typedArray.getDimensionPixelOffset(R.styleable.ColorValuePicker_markStrokeWidth,dp2px(context,this.markStrokeWidth));
        int resid=typedArray.getResourceId(R.styleable.ColorValuePicker_srcCompat,0); //获取 图片资源id
        if(resid!=0) {
            this.centerBitmap = VectorDrawableToBitmap(resid);  //从资源ID矢量图形转为位图
            if (this.centerBitmap == null) {
                this.centerBitmap = BitmapFactory.decodeResource(getResources(), resid);//从图片资源中获取位图
            }
        }
        centerImageAlpha=typedArray.getInt(R.styleable.ColorValuePicker_centerImageAlpha,centerImageAlpha);
        isTint=typedArray.getResourceId(R.styleable.ColorValuePicker_tint,0)!=0;
        if(isTint) {
            tintColor = typedArray.getColor(R.styleable.ColorValuePicker_tint, tintColor);
        }
        checked=typedArray.getBoolean(R.styleable.ColorValuePicker_checked,checked);
        // currentColor=typedArray.getColor(R.styleable.ColorValuePicker_currentColor,0);
        String hexColor=typedArray.getString(R.styleable.ColorValuePicker_currentColor);  //通过字符串方式获取16进制颜色字符串
        if(hexColor!=null) {   //判断字符串是否为空
            //计算当前颜色，
            float hsv[] = new float[3];
            currentColor=Color.parseColor(hexColor);
            ColorUnit.colorToHSV(currentColor, hsv);//得到当前显示的颜色
            this.angle=hsv[0]+90;
            if(this.angle>360) this.angle-=360;
        }else{
            //将当前选择器圆点角度转为hsv颜色的标准角度
            float tempAngle=this.angle-90;
            if(tempAngle<0) tempAngle+=360.0f;
            currentColor= ColorUnit.HSVToColor(255,tempAngle,1,1);//这里的角度必须要减90度，因为hsv的0度颜色为红色
        }
        int mPickerStyle= typedArray.getInteger(R.styleable.ColorValuePicker_colorPickerStyle,0);
        if(mPickerStyle==0){
            this.colorPickerStyle=PickerStyle.MARK_RING_INNER;
        }else if(mPickerStyle==1){
            this.colorPickerStyle=PickerStyle.MARK_RING_OUTER;
        }else if(mPickerStyle==2){
            this.colorPickerStyle=PickerStyle.MARK_RING_DOWN_OUTER;
        }
        init();
        typedArray.recycle();
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // RingWidth = dp2px(getContext(), 20);
        width = getMeasuredWidth();
        height = getMeasuredHeight();
        //四边最保留区域（非绘图区，最少保留4给像素）
        int paddingLeft,paddingRight;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            paddingLeft=(getPaddingStart()==0?getPaddingLeft():getPaddingStart())+4;
            paddingRight=(getPaddingEnd()==0?getPaddingRight():getPaddingEnd())+4;
        }else{
            paddingLeft=getPaddingLeft()+4;
            paddingRight=getPaddingRight()+4;
        }
        int paddingTop=getPaddingTop()+4;
        int paddingBottom=getPaddingBottom()+4;
        if(colorPickerStyle==PickerStyle.MARK_RING_OUTER ||colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER){
            paddingLeft+=RingWidth/2;
            paddingRight+=RingWidth/2;
            paddingTop+=RingWidth/2;
            paddingBottom+=RingWidth/2;
        }
        int size = ((width-paddingLeft-paddingRight) > (height-paddingTop-paddingBottom)) ? height-paddingTop-paddingBottom : width-paddingLeft-paddingRight; //选择最小
        circleX =paddingLeft+(width-paddingLeft-paddingRight)/2;//(width+getPaddingLeft()-getPaddingRight()) / 2;  //确定圆的x坐标中心点
        circleY = paddingTop+(height-paddingTop-paddingBottom )/2;//height / 2;   //确定圆的Y坐标中心点
        //分辨率适配:获取圆环的宽度 圆环的半径 内部圆的半径
        outerRadius=size/2;//-dp2px(getContext(),4);//-barWidth*2;
        innerRadius=outerRadius-RingWidth;
        shader=new SweepGradient(circleX, circleY, mCircleColors, null);//角度渐变着色器,颜色平均分配
        paintCircleRing.setShader(shader);//设置着色器
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /***********************画色环*****************************/
        Path path=new Path();
        RectF outerRect=new RectF(circleX-outerRadius,circleY-outerRadius,circleX+outerRadius,circleY+outerRadius);
        RectF innerRect=new RectF(circleX-innerRadius,circleY-innerRadius,circleX+innerRadius,circleY+innerRadius);
        //这里内圆和外圆的开始角一定要错开，否则路径无法闭合，填充出来的就不是圆环
        path.addArc(outerRect,0,360);
        path.arcTo(innerRect,359,-360);
        path.close();
        canvas.drawPath(path,paintCircleRing);
        /******************* 绘制颜色选择器*************************/
        setInitMarkToXY(this.angle);
        float frameRadius;
        if(colorPickerStyle==PickerStyle.MARK_RING_INNER||colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER){
            frameRadius =RingWidth/2;
        }else{
            frameRadius =RingWidth;
        }
        if(this.markAutoColor) {
            paintSelecter.setColor(interpCircleColor(mCircleColors, this.angle));
        }
        if(colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER && isMarkPointRangeDown){
            Paint spreadPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
            spreadPaint.setStyle(Paint.Style.FILL);
            int spreadColor;
            if(this.markAutoColor) {
                spreadColor=interpCircleColor(mCircleColors, this.angle);

            }else{
                spreadColor=colorMarkFill;
            }
            Shader mShader = new RadialGradient(markPointX, markPointY, RingWidth, new int[]{spreadColor, ColorUnit.toColor(spreadColor,30)}, null,Shader.TileMode.CLAMP);
            spreadPaint.setShader(mShader);
            canvas.drawCircle(markPointX, markPointY, RingWidth, spreadPaint);  //绘制半透明扩散
        }else{
            canvas.drawCircle(markPointX, markPointY, frameRadius, paintSelecter);//绘制选择器圆点
        }
        if(markStroke||colorPickerStyle!=PickerStyle.MARK_RING_OUTER) {//绘制选择器边框
            float radius=frameRadius-markStrokeWidth/2;//重新计算圆的半径，用于解决线宽向内扩充的问题
            canvas.drawCircle(markPointX, markPointY, radius, paintSelecterStroke); //绘制选择器圆点边框
        }
        /*********************绘制中心按钮*************************/
        centerRadius=innerRadius/2;
        if(checked) {  //复选状态为选择状态
            centerPaint.setShader(new RadialGradient(circleX, circleY, innerRadius, new int[]{currentColor, 0x00ffffff}, null, Shader.TileMode.CLAMP));
            centerPaint.setStyle(Paint.Style.FILL);
            canvas.drawCircle(circleX, circleY, innerRadius, centerPaint);//画中心圆
            centerPaint.setShader(null);
            centerPaint.setColor(currentColor);
            canvas.drawCircle(circleX, circleY, centerRadius, centerPaint);//画中心圆
        }
        //绘制中心按钮边框
        centerPaint.setStyle(Paint.Style.STROKE);
        centerPaint.setColor(0xffffffff);
        centerPaint.setStrokeWidth(3);
        canvas.drawCircle(circleX,circleY, centerRadius,  centerPaint);//画中心圆边框
        if(centerBitmap!=null) {
            int imgRadius= (int) (centerRadius / 2);
            if(tintArrayColor!=null && tintArrayColor.length>1) {
                centerBitmap = getGradientBitmap(centerBitmap,tintArrayColor);
                canvas.drawBitmap(centerBitmap, null, new Rect((int) (circleX - imgRadius), (int) (circleY-imgRadius), (int)(circleX + imgRadius), (int) (circleY+imgRadius)), null);
            }else{
                canvas.drawBitmap(centerBitmap, null, new Rect((int) (circleX - imgRadius), (int) (circleY-imgRadius), (int)(circleX + imgRadius), (int) (circleY+imgRadius)), isTint?centerBitmapPaint:null);//centerBitmapPaint
            }
        }

//        Paint paint = new Paint();
//        paint.setTextSize(25);
//        paint.setColor(Color.RED);
//
//        paint.setFlags(Paint. UNDERLINE_TEXT_FLAG);
//        paint.setColor(Color.GREEN);
//        canvas.drawText("My Underline Text", 50, 140, paint);
        //canvas.drawText("角度:"+this.angle,20,20,centerPaint);
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        if (isPointRange(x,y) || isMarkPointRange(x, y)) {  //如果触摸坐标在圆环或颜色选择器上时
            getParent().requestDisallowInterceptTouchEvent(true); //请求请求所有的视图件禁止接收触摸事件
        }
        return super.dispatchTouchEvent(event);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: //触摸按下
                //判断触摸按下的坐标是否在圆环上
                if (isPointRange(x,y)){
                    if(onColorValuePickerChangeListener !=null){
                        onColorValuePickerChangeListener.onStartTrackingTouch(this);
                    }
                    isRingDown=true; //将标志改为触摸按下圆环
                    //判断触摸按下的坐标是否非选择器上，不在选择器上就执行旋转操作
                    if (!isMarkPointRange(x, y)) {
                        this.isFromUser=true;
                        if(colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER)
                            isMarkPointRangeDown=true;
                        setAngle(x, y);   //设置旋转角度
                    }else{
                        isMarkPointRangeDown=true;
                        if(colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER)
                            invalidate();
                    }
                }else{
                    isRingDown=false;  //将标志设置未非圆环上按下
                    if (isMarkPointRange(x, y)) {  //这里用于处理选择器圆点大于圆环宽度的情况
                        isMarkPointRangeDown=true;
                        if(colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER)
                            invalidate();
                    }
                }
                if(isCenterButton(x,y)) {
                    timer=new Timer();//长按计时器
                    timerTaskLongDown=new TimerTask() {
                        @Override
                        public void run() {
                            isButtonClick=false;
                            if(onLongClickListener!=null){
                                isLongClick=onLongClickListener.onLongClick(ColorValuePicker.this);  //触发长按事件
                            }
                        }
                    };
                    isButtonClick=true;
                    timer.schedule(timerTaskLongDown,LONGPRESSTIME,1000*60*60*24);
                    //记录上次点击的位置，用来进行移动的模糊处理
                    lastX=x;
                    lastY=y;
                }
                break;
            case MotionEvent.ACTION_MOVE: //触摸移动
                if(isRingDown) {  //如果为圆环按下状态
                    if(isMarkPointRangeDown){ //如果为选择器按下状态
                        this.isFromUser=true;
                        setAngle(x, y);  //设置旋转角度
                    }else {
                        if (isMarkPointRange(x, y)) {  //判断触摸按下的坐标是否非选择器上
                            isMarkPointRangeDown=true; //将标志改为选择器按下状态
                            if(colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER)
                                invalidate();
                        }
                    }
                }else{
                    if(isMarkPointRangeDown){   //处理选择器圆点大于圆环宽度的情况
                        this.isFromUser=true;
                        setAngle(x, y);  //设置旋转角度
                    }
                }
                //处理长按判断
                if(isButtonClick) {
                    if (Math.abs(lastX - x) > 20 || Math.abs(lastY - y) > 20) {   //判断是否移动
                        isButtonClick=false;
                        //取消计时
                        if(timerTaskLongDown!=null)  timerTaskLongDown.cancel();
                        if(timer!=null) timer.cancel();
                    }else{
                        return true;
                    }
                }
                break;
            case MotionEvent.ACTION_UP://触摸弹起
                if(isRingDown||isMarkPointRangeDown){
                    if(onColorValuePickerChangeListener !=null){
                        onColorValuePickerChangeListener.onStopTrackingTouch(this);
                    }
                }
                //if(colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER)
                //计算当前颜色，
                float hsv[]=new float[3];
                ColorUnit.colorToHSV(currentColor,hsv);//得到当前显示的颜色
                //将当前选择器圆点角度转为hsv颜色的标准角度
                float tempAngle=this.angle-90;
                if(tempAngle<0) tempAngle+=360.0f;
                //将当前hsv代表的颜色替换角度后重新生成当前新颜色（这样的目的是只改变色调，饱和度和亮度保存不变）
                currentColor= ColorUnit.HSVToColor(255,tempAngle,hsv[1],hsv[2]);
                if(isCenterButton(x,y) && !isLongClick){
                    setChecked(!checked,true);  //将状态取反
                    if(onClickListener!=null){   //触发单击事件
                        onClickListener.onClick(this);
                    }
                }
                invalidate();
                //取消计时
                if(timerTaskLongDown!=null)  timerTaskLongDown.cancel();
                if(timer!=null) timer.cancel();
                isRingDown=false;
                isMarkPointRangeDown=false;
                isButtonClick=false;
                isLongClick=false;
                break;
            case MotionEvent.ACTION_CANCEL: //取消操作
                Log.e("onTouchEvent","取消操作");
                break;
        }
        return true;
    }
    /**************************公共属性及方法******************************/
    /**
     * 设置侦听器以接收RingColorPicker更改的通知。还提供用户在RingColorPicker中启动和停止触摸手势的通知。
     * @param listener 通知侦听器
     */
    public void setOnRingColorPickerChangeListener(@Nullable OnColorValuePickerChangeListener listener){
        this.onColorValuePickerChangeListener = listener;
    }
    /**
     * 注册此按钮的选中状态更改时要调用的回调。
     * @param listener 调用选中状态更改的回调
     */
    public void setOnCheckedChangeListener( @Nullable OnCheckedChangeListener listener){
        this.onCheckedChangeListener=listener;
    }
    /**
     * 注册颜色选择器中心按钮单击事件
     * @param onClickListener 将运行的回调
     */
    @Override
    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }
    /**
     * 注册颜色选择器中心按钮长按事件
     * @param onLongClickListener 将运行的回调
     */
    @Override
    public void setOnLongClickListener(OnLongClickListener onLongClickListener) {
        this.onLongClickListener = onLongClickListener;
    }

    /**
     * 设置选择器再圆环的角度
     * @param angle 角度
     */
    public void setAngle(float angle) {
        this.angle = angle;
        this.isFromUser=false;
        invalidate();
        ImageView imageView;
    }
    /**获取选择器再圆环上的角度*/
    public float getAngle() {
        return angle;
    }
    /**
     * 设置圆环宽度
     * @param ringWidth
     */
    public void setRingWidth(int ringWidth) {
        RingWidth = dp2px(getContext(),ringWidth);
        invalidate();
    }
    /**获取圆环宽度*/
    public int getRingWidth() {
        return RingWidth;
    }
    /**
     * 设置选择器背景颜色
     * @param color 颜色值
     */
    public void setMarkBackground(int color){
        this.colorMarkFill =color;
        paintSelecter.setColor(colorMarkFill );
        invalidate();
    }
    /**
     * 设置选择器背景颜色
     * @param color Color颜色对象
     */
    public void setMarkBackground(Color color){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            setMarkBackground(color.toArgb());
        }
    }
    /**
     * 设置选择器背景颜色
     * @param colorString 16进制颜色字符串。如"#RRGGBB 或 #AARRGGBB"
     */
    public void setMarkBackground(String colorString){
        try {
            int color=Color.parseColor(colorString);
            setMarkBackground(color);
        } catch (Exception e) {
            Log.e("setSelecterBackground",e.getMessage());
        }
    }
    /**获取选择器背景色*/
    public int getMarkBackground(){
        return colorMarkFill ;
    }
    /**
     * 设置选择器边框杨色
     * @param color 颜色值
     */
    public void setMarkStrokeColor(int color){
        this.colorMarkStroke=color;
        paintSelecterStroke.setColor(colorMarkStroke);
        invalidate();
    }
    /**
     * 设置选择器边框杨色
     * @param color Color颜色对象
     */
    public void setMarkStrokeColor(Color color){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            this.setMarkStrokeColor( color.toArgb());
        }
    }
    /**
     * 设置选择器边框杨色
     * @param colorString 16进制颜色字符串。如"#RRGGBB 或 #AARRGGBB"
     */
    public void setMarkStrokeColor(String colorString){
        try {
            int color=Color.parseColor(colorString);
            setMarkStrokeColor(color);
        } catch (Exception e) {
            Log.e("setSelecterStroke",e.getMessage());
        }
    }
    /**获取选择器边框颜色*/
    public int getMarkStrokeColor(){
        return colorMarkStroke;
    }
    /**
     * 设置选择器边框(只对ColorPickerStyle=MARK_RING_OUTER有效，另外两种样式必须具有边框)
     * @param stroke
     */
    public void setMarkStroke(boolean stroke){
        this.markStroke=stroke;
        invalidate();
    }
    /**获取选择器边框*/
    public boolean isMarkStroke() {
        return markStroke;
    }
    /**
     * 设置选择器样式
     * @param colorPickerStyle PickerStyle枚举
     */
    public void setColorPickerStyle(PickerStyle colorPickerStyle) {
        this.colorPickerStyle = colorPickerStyle;
        //重新初始化以下参数
        //四边最保留区域（非绘图区，最少保留4给像素）
        int paddingLeft,paddingRight;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            paddingLeft=(getPaddingStart()==0?getPaddingLeft():getPaddingStart())+4;
            paddingRight=(getPaddingEnd()==0?getPaddingRight():getPaddingEnd())+4;
        }else{
            paddingLeft=getPaddingLeft()+4;
            paddingRight=getPaddingRight()+4;
        }
        int paddingTop=getPaddingTop()+4;
        int paddingBottom=getPaddingBottom()+4;
        if(colorPickerStyle==PickerStyle.MARK_RING_OUTER ||colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER){
            paddingLeft+=RingWidth/2;
            paddingRight+=RingWidth/2;
            paddingTop+=RingWidth/2;
            paddingBottom+=RingWidth/2;
        }
        int size = ((width-paddingLeft-paddingRight) > (height-paddingTop-paddingBottom)) ? height-paddingTop-paddingBottom : width-paddingLeft-paddingRight; //选择最小
        circleX =paddingLeft+(width-paddingLeft-paddingRight)/2;//(width+getPaddingLeft()-getPaddingRight()) / 2;  //确定圆的x坐标中心点
        circleY = paddingTop+(height-paddingTop-paddingBottom )/2;//height / 2;   //确定圆的Y坐标中心点
        //分辨率适配:获取圆环的宽度 圆环的半径 内部圆的半径
        outerRadius=size/2;//-dp2px(getContext(),4);//-barWidth*2;
        innerRadius=outerRadius-RingWidth;
        shader=new SweepGradient(circleX, circleY, mCircleColors, null);//角度渐变着色器
        paintCircleRing.setShader(shader);//设置着色器

        invalidate();
    }
    /**获取选择器样式*/
    public PickerStyle getColorPickerStyle() {
        return colorPickerStyle;
    }

    /**
     * 使用选择器自动色
     * @param autoColor
     */
    public void setMarkAutoColor(boolean autoColor){
        this.markAutoColor=autoColor;
        invalidate();
    }
    /**获取选择器自动颜色状态 */
    public boolean isMarkAutoColor() {
        return markAutoColor;
    }

    /**
     * 设置扩散效果透明度
     * @param alpha 透明度(0-255之间)
     */
    public void setSpreadAlpha(int alpha) {
        if(alpha<0)
            alpha=0;
        else if(alpha>255)
            alpha=255;
        this.spreadAlpha = alpha;
        invalidate();
    }
    /**
     * 设置扩散效果透明度
     * @param alpha 透明度(0-1之间)
     */
    public void setSpreadAlpha(float alpha) {
        if(alpha<0)
            alpha=0;
        else if(alpha>1)
            alpha=1;
        setSpreadAlpha((int) (alpha*255));
    }
    /**获取扩散效果透明度*/
    public int getSpreadAlpha() {
        return spreadAlpha;
    }
    /**
     * 设置选择器圆点边框宽度
     * @param markStrokeWidth
     */
    public void setMarkStrokeWidth(int markStrokeWidth) {
        this.markStrokeWidth = dp2px(getContext(),markStrokeWidth);
        paintSelecterStroke.setStrokeWidth(this.markStrokeWidth);
        invalidate();
    }
    /**获取选择器圆点边框宽度*/
    public int getMarkStrokeWidth() {
        return markStrokeWidth;
    }

    /**
     * 设置中心图片位图
     * @param bm 位图
     */
    public void setCenterImageBitmap(Bitmap bm){
        centerBitmap=bm;
        invalidate();
    }

    /**
     * 设置中心图片Drawable
     * @param drawable
     */
    public void setCenterImageDrawable(Drawable drawable){
        setCenterImageBitmap(DrawableToBitmap(drawable));
    }


    /**
     * 设置中心图片资源ID
     * @param resId 资源id
     */
    public void setCenterImageResource(int resId){
        setCenterImageBitmap(BitmapFactory.decodeResource(getResources(),resId));
    }

    /**
     * 设置中心图片图标
     * @param icon 图标
     */
    public void setImageIcon(Icon icon){
        if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
            BitmapDrawable bd=(BitmapDrawable) icon.loadDrawable(this.getContext());
            setCenterImageBitmap(bd.getBitmap());
        }
    }
    /**
     * 设置中心图片uri地址
     * @param uri
     */
    public void setCenterImageURI(Uri uri){
        try {
            Bitmap bm= MediaStore.Images.Media.getBitmap(this.getContext().getContentResolver(), uri);
            setCenterImageBitmap(bm);
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,e.getMessage());
        }
    }
    /**获取中心图标位图*/
    public Bitmap getCenterImageBitmap(){
        return centerBitmap;
    }
    /**
     * 设置中心图片透明度
     * @param alpha 透明度(0-255)
     */
    public void setCenterImageAlpha(int alpha){
        centerImageAlpha=alpha;
        centerBitmapPaint .setAlpha( this.centerImageAlpha);
        invalidate();
    }
    /**获取中心图片透明度*/
    public float getCenterImageAlpha() {
        return centerImageAlpha;
    }

    /**
     * 设置中心按钮复选状态
     * @param checked 选择状态
     */
    public void setChecked(boolean checked) {
        setChecked(checked,false);
        invalidate();
    }
    /**获取中心按钮选择状态*/
    public boolean isChecked() {
        return checked;
    }
    /**
     * 设置着色器颜色
     * @param tintColor
     */
    public void setTintColor(int tintColor) {
        this.tintColor = tintColor;
        centerBitmapPaint.setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
        isTint=true;
        invalidate();
    }
    /**
     * 设置着色器颜色
     * @param tintColor
     */
    public void setTintColor(Color tintColor) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if(tintColor!=null) {
                setTintColor(tintColor.toArgb());
            }else{
                isTint=false;
                invalidate();
            }
        }
    }
    /**
     * 设置着色器颜色
     * @param colorString
     */
    public void setTintColor(String colorString) {
        try {
            setTintColor(Color.parseColor(colorString));
        } catch (Exception e) {
            Log.e("setTintColor",e.getMessage());
            isTint=false;
            invalidate();
        }
    }
    /**获取着色器颜色**/
    public int getTintColor() {
        return tintColor;
    }

    /**
     * 设置图片着色器渐变色
     * @param arrayColor
     */
    public void setTintArrayColor(int[] arrayColor){
        tintArrayColor=arrayColor;
        invalidate();
    }
    /**获取着色器渐变色*/
    public int[] getTintArrayColor() {
        return tintArrayColor;
    }
    /**
     * 设置当前颜色
     * @param color 需要改变的当前颜色
     */
    public void setCurrentColor(int color) {
        this.currentColor = color;
        float hsv[]=new float[3];
        ColorUnit.colorToHSV(this.currentColor,hsv);//得到当前显示的颜色
        this.angle=hsv[0]+90;
        if(this.angle>360) this.angle-=360;
        this.isFromUser=false;
        invalidate();
    }
    /**
     * 设置当前颜色
     * @param color 需要改变的当前颜色
     */
    public void setCurrentColor(Color color) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            setCurrentColor(color.toArgb());
        }
    }
    /**
     * 设置当前颜色
     * @param colorString 需要改变的当前颜色
     */
    public void setCurrentColor(String colorString) {
        try {
            setCurrentColor(Color.parseColor(colorString));
        } catch (Exception e) {
            Log.e("setCurrentColor",e.getMessage());
        }
    }
    /**
     * 通过HSV设置当前颜色
     * @param hsv  3元素数组。
     *  <ul>
     *  <li>hsv[0]是色调（[0..360[）</li>
     *  <li>hsv[1]色饱和（[0…1]\）</li>
     *  <li>hsv[2]是值（[0…1]\）</li>
     *  </ul>
     */
    public void setCurrentColor(float[] hsv){
        setCurrentColor(ColorUnit.HSVToColor(hsv));
    }
    /**
     * 通过HSV设置当前颜色
     * @param hue 色调（[0..360[）
     * @param saturation 色饱和（[0…1]\）
     * @param value 亮度值（[0…1]\）
     */
    public void setCurrentColor(float hue,float saturation,float value){
        setCurrentColor(ColorUnit.HSVToColor(hue,saturation,value));
    }
    /**获取当前颜色**/
    public int getCurrentColor() {
        return currentColor;
    }

    /**
     * 获取渐变混色位图
     * @param drawableId 资源ID
     * @param colors 渐变颜色数组
     * @return
     */
    public  Bitmap getGradientBitmap( int drawableId, int[] colors) {
        //android不允许直接修改res里面的图片，所以要用copy方法
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), drawableId)
                .copy(Bitmap.Config.ARGB_8888, true);
        addGradient(bitmap, colors);
        return bitmap;
    }
    /**
     * 获取渐变混色位图
     * @param bitmap 需要渐变混色的位图
     * @param colors 渐变颜色数组
     * @return
     */
    public  Bitmap getGradientBitmap( Bitmap bitmap, int[] colors) {
        Bitmap tempbitmap=bitmap.copy(Bitmap.Config.ARGB_8888, true);
        addGradient(tempbitmap, colors);
        return tempbitmap;
    }
    /***********************所有方法****************************/
    /**
     * 初始化
     */
    private void init() {
        // 渐变色环参数
        paintCircleRing = new Paint(Paint.ANTI_ALIAS_FLAG);
        paintCircleRing.setAntiAlias(true);
        paintCircleRing.setStyle(Paint.Style.FILL);

        //选择器
        paintSelecter = new Paint(Paint.ANTI_ALIAS_FLAG);
        paintSelecter.setColor(colorMarkFill );
        paintSelecter.setAntiAlias(true);
        paintSelecter.setStrokeWidth(10);
        //选择器描边画笔
        // if(markStroke||colorPickerStyle!=PickerStyle.MARK_RING_OUTER) {//绘制选择器边框
        paintSelecterStroke = new Paint(Paint.ANTI_ALIAS_FLAG);//创建画笔，并边缘平滑
        paintSelecterStroke.setColor(colorMarkStroke);
        paintSelecterStroke.setStyle(Paint.Style.STROKE);
        paintSelecterStroke.setStrokeWidth(this.markStrokeWidth);
        // }
        //初始化中心圆的Paint对象
        centerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        centerPaint.setAntiAlias(true);
        // centerPaint.setColor(centerCircleColor);
        centerPaint.setStrokeWidth(CENTER_CIRCLE_WIDTH);

        centerBitmapPaint = new Paint();
        centerBitmapPaint .setStyle( Paint.Style.STROKE );
        centerBitmapPaint .setAlpha( this.centerImageAlpha);
        centerBitmapPaint.setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
    }
    /**
     * dp转像素
     * @param context 应用上下文
     * @param dpVal 需要转换的dp值
     * @return 返回像素未单位的值
     */
    private static int dp2px(Context context, float dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, context.getResources().getDisplayMetrics());
    }
    /**
     * 设置选择器坐标
     * @param angle 选择器实在的坐标
     */
    private void setInitMarkToXY(float angle) {
        markPointX = (float) (circleX + (outerRadius- RingWidth/2)* Math.sin(angle * Math.PI / 180));
        markPointY = (float) (circleY - (outerRadius- RingWidth/2) * Math.cos(angle * Math.PI / 180));
        if(onColorValuePickerChangeListener !=null && oleAngle!=angle){
            onColorValuePickerChangeListener.onChangeListener(this,this.angle,this.isFromUser);
            oleAngle=angle;
        }
        this.isFromUser=false;
    }

    /**
     * 返回指定坐标是否再选择器上
     * @param x
     * @param y
     * @return true 在选择器上，false 不在选择器上
     */
    private boolean isMarkPointRange(float x, float y) {
        float centralOffset= (float) Math.sqrt(Math.pow(x-markPointX,2)+Math.pow(y-markPointY,2));//计算指定点到圆心偏移量
        if(colorPickerStyle==PickerStyle.MARK_RING_INNER||colorPickerStyle==PickerStyle.MARK_RING_DOWN_OUTER) {
            return centralOffset <= (RingWidth / 2);
        }else{
            return centralOffset <= RingWidth ;
        }
    }

    /**
     * 指定坐标是否在中心按钮上
     * @param x
     * @param y
     * @return true 在按钮上，false 不在
     */
    private boolean isCenterButton(float x,float y){
        float centralOffset= (float) Math.sqrt(Math.pow(x-circleX,2)+Math.pow(y-circleY,2));//计算指定点到圆心偏移量
        return centralOffset<=innerRadius/2;
    }


    /**
     * 指定坐标是否在圆环上
     * @param x
     * @param y
     * @return true 再圆环上，false 不在圆环上
     */
    private boolean isPointRange(float x,float y){
        float centralOffset= (float) Math.sqrt(Math.pow(x-circleX,2)+Math.pow(y-circleY,2));//计算指定点到圆心偏移量
        return centralOffset>=innerRadius && centralOffset<=outerRadius;
    }

    /**
     * 根据指定坐标设置选择器旋转角度
     * @param x
     * @param y
     */
    private void setAngle(float x,float y) {
        markPointX = (float) (circleX + outerRadius * Math.cos(Math.atan2(x - circleX, circleY - y) - (Math.PI / 2)));
        markPointY = (float) (circleY + outerRadius * Math.sin(Math.atan2(x - circleX, circleY - y) - (Math.PI / 2)));
        float degrees = (float) ((float) ((Math.toDegrees(Math.atan2(x - circleX, circleY - y)) + 360.0)) % 360.0);
        // 注意：为负数要加360°
        if (degrees < 0)
            degrees += 2 * Math.PI;
        //角度四舍五入
        this.angle = Math.round(degrees);
        invalidate(); //刷新ui
    }
    /**
     * 设置中心按钮复选状态
     * @param checked 选择状态
     * @param isFromUser 用户改变
     */
    private void setChecked(boolean checked,boolean isFromUser) {
        this.checked = checked;
        if(onCheckedChangeListener!=null){
            onCheckedChangeListener.onCheckedChanged(this,checked,isFromUser);
        }
    }
    /**
     * 获取圆环上颜色
     * @param colors 圆环上面使用到的颜色数组
     * @param angle 角度
     * @return 返回int颜色
     */
    private int interpCircleColor(int colors[], float angle) {
        angle -= 90;
        if (angle < 0)
            angle += 360;
        float p = angle * (colors.length - 1) / 360;
        int i = (int) p;
        p -= i;
        int c0 = colors[i];
        int c1 = colors[i + 1];
        int a = ave(Color.alpha(c0), Color.alpha(c1), p);
        int r = ave(Color.red(c0), Color.red(c1), p);
        int g = ave(Color.green(c0), Color.green(c1), p);
        int b = ave(Color.blue(c0), Color.blue(c1), p);
        return Color.argb(a, r, g, b);
    }
    private int ave(int s, int d, float p) {
        return s + Math.round(p * (d - s));
    }

    /**
     * Drawable转位图
     * @param drawable
     * @return
     */
    private Bitmap DrawableToBitmap(Drawable drawable){
        BitmapDrawable bd=null;
        try {
            bd = (BitmapDrawable) drawable;
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(bd!=null) {
            return bd.getBitmap();
        }else{
            int width = drawable.getIntrinsicWidth();
            int height = drawable.getIntrinsicHeight();
            Bitmap bitmap = Bitmap.createBitmap(width, height,
                    drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888: Bitmap.Config.RGB_565);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0,0,width,height);
            drawable.draw(canvas);
            return bitmap;
        }
    }

    /**
     * 从资源ID中的矢量图转位图
     * @param resId 资源id
     * @return
     */
    private Bitmap VectorDrawableToBitmap(int resId){
        Drawable drawable = ContextCompat.getDrawable(getContext(),resId);
        drawable = (DrawableCompat.wrap(drawable)).mutate();
        return DrawableToBitmap(drawable);
    }
    /**
     * 给位图添加线形着色
     * @param originalBitmap 需要着色的旧位图
     * @param colors 颜色数组,如果为null或数组长度为0，默认着#ff9900色
     * @return 返回着色后的位图
     */
    private Bitmap addGradient(Bitmap originalBitmap, int[] colors) {//给originalBitmap着渐变色
        if (colors == null || colors.length == 0) {//默认色处理
            colors = new int[]{Color.parseColor("#ff9900"), Color.parseColor("#ff9900")};
        } else if (colors.length == 1) {//单色处理
            int[] newColor = new int[]{colors[0], colors[0]};
            colors = newColor;
        }
        int width = originalBitmap.getWidth();
        int height = originalBitmap.getHeight();

        Canvas canvas = new Canvas(originalBitmap);//Canvas中Bitmap是用来保存像素，相当于画纸
        Paint paint = new Paint();
        LinearGradient shader = new LinearGradient(0, 0, width, height, colors, null, Shader.TileMode.CLAMP);//shader:着色器，线性着色器设置渐变从左上坐标到右下坐标
        paint.setShader(shader);//设置着色器
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//设置图像混合模式
        canvas.drawRect(0, 0, width, height, paint);
        return originalBitmap;
    }

    /**
     * 颜色工具
     */
    public static class ColorUnit extends Color {
        public ColorUnit(){
            super();
        }
        /**
         * 将RGB组件转换为HSV。
         * <ul>
         * <li>hsv[0]是色调（[0..360[）</li>
         * <li>hsv[1]已饱和\（[0…1]\）</li>
         * <li>hsv[2]是值\（[0…1]\）</li>
         * </ul>
         * @param red 红色分量值（[0..255]）
         * @param green 绿色分量值（[0..255]）
         * @param blue 蓝色分量值（[0..255]）
         * @param hsv 3元素数组，用于保存生成的HSV组件。
         */
        public static void RGBToHSV(int red,int green, int blue,@Size(3) float hsv[]){
            Color.RGBToHSV(red,green,blue,hsv);
        }
        /**
         * 将RGB组件转换为HSV。
         * <ul>
         * <li>hsv[0]是色调（[0..360[）</li>
         * <li>hsv[1]已饱和（[0…1]\）</li>
         * <li>hsv[2]是值（[0…1]\）</li>
         * </ul>
         * @param red 红色的分量（[0..1]）
         * @param green 绿色的分量（[0..1]）
         * @param blue 蓝色的分量（[0..1]）
         * @param hsv 3元素数组，用于保存生成的HSV组件。
         */
        public static void RGBToHSV(float red, float green, float blue, @Size(3) float hsv[]){
            if(red<0) {
                red = 0;
            }else if(red>1){
                red = 1;
            }
            if(green<0) {
                green = 0;
            }else if(green>1){
                green = 1;
            }
            if(blue<0) {
                blue = 0;
            }else if(blue>1){
                blue = 1;
            }
            Color.RGBToHSV((int)(red*255.0f),(int)(green*255.0f),(int)(blue*255.0f),hsv);
        }

        /**
         * 将HSV组件转为RGB组件
         * @param hsv 3元素数组。
         * <ul>
         * <li>hsv[0]是色调（[0..360[）</li>
         * <li>hsv[1]色饱和（[0…1]\）</li>
         * <li>hsv[2]是值（[0…1]\）</li>
         * </ul>
         * @param rgb 3元素数组，用于保存生成的HSV组件。
         * <ul>
         * <li>rgb[0]颜色的红色分量（[0..1]）</li>
         * <li>rgb[1] 颜色的绿色分量（[0..1]）</li>
         * <li>rgb[2] 颜色的蓝色量（[0..1]）</li>
         * </ul>
         */
        public static void HSVToRGB(float hsv[], @Size(3) float rgb[]){
            int color=Color.HSVToColor(hsv);
            rgb[0]=Color.red(color);
            rgb[1]=Color.green(color);
            rgb[2]=Color.blue(color);
          //  Color.colorToHSV();
        }
        /**
         * 将HSV组件转为RGB组件
         * @param hue 是色调（[0..360[）
         * @param saturation 色饱和（[0…1]\）
         * @param value 亮度值（[0…1]\）
         * @param rgb 3元素数组，用于保存生成的HSV组件。
         *      <ul>
         *      <li>rgb[0]颜色的红色分量（[0..1]）</li>
         *      <li>rgb[1] 颜色的绿色分量（[0..1]）</li>
         *      <li>rgb[2] 颜色的蓝色量（[0..1]）</li>
         *      </ul>
         */
        public static void HSVToRGB(float hue,float saturation,float value, @Size(3) float rgb[]){
            float hsv[]={hue,saturation,value};
            HSVToRGB(hsv,rgb);
        }

        /**
         * 将HSV组件转换为ARGB颜色。Alpha设置为0xFF。
         * @param hue 色调（[0..360[）
         * @param saturation 色饱和（[0…1]\）
         * @param value 亮度值（[0…1]\）
         * @return Argb颜色
         */
        public static int HSVToColor(float hue,float saturation,float value){
            float hsv[]={hue,saturation,value};
            return   Color.HSVToColor(hsv);
        }

        /**
         * 将HSV组件转换为ARGB颜色。alpha分量通过不变。
         * @param alpha 返回的argb颜色的alpha分量。
         * @param hue 色调（[0..360[）
         * @param saturation 色饱和（[0…1]\）
         * @param value 亮度值（[0…1]\）
         * @return Argb颜色
         */
        public static int HSVToColor(@IntRange(from = 0, to = 255) int alpha, float hue, float saturation, float value){
            float hsv[]={hue,saturation,value};
            return   Color.HSVToColor(alpha,hsv);
        }
        /**
         * 从范围（[0..1]）内的alpha、red、green、blue float组件返回一个颜色int。如果组件超出范围，则返回的颜色未定义。
         * @param alpha 颜色的Alpha分量（[0..1]）
         * @param red 颜色的红色分量（[0..1]）
         * @param green 颜色的绿色分量（[0..1]）
         * @param blue 颜色的蓝色量（[0..1]）
         * @return
         */
        @ColorInt
        public static int argb(float alpha, float red, float green, float blue){
            if(alpha<0) {
                alpha = 0;
            }else if(alpha>1){
                alpha = 1;
            }
            if(red<0) {
                red = 0;
            }else if(red>1){
                red = 1;
            }
            if(green<0) {
                green = 0;
            }else if(green>1){
                green = 1;
            }
            if(blue<0) {
                blue = 0;
            }else if(blue>1){
                blue = 1;
            }
            return ((int) (alpha * 255.0f + 0.5f) << 24) |
                    ((int) (red   * 255.0f + 0.5f) << 16) |
                    ((int) (green * 255.0f + 0.5f) <<  8) |
                    (int) (blue  * 255.0f + 0.5f);
        }
        /**
         * 从范围（[0..1]）内的红色、绿色、蓝色浮点组件返回一个颜色int。alpha组件隐式地为1.0（完全不透明）。如果组件超出范围，则返回的颜色未定义。
         * @param red 颜色的红色分量（[0..1]）
         * @param green 颜色的绿色分量（[0..1]）
         * @param blue 颜色的蓝色量（[0..1]）
         * @return
         */
        @ColorInt
        public static int rgb(float red, float green, float blue) {
            if(red<0) {
                red = 0;
            }else if(red>1){
                red = 1;
            }
            if(green<0) {
                green = 0;
            }else if(green>1){
                green = 1;
            }
            if(blue<0) {
                blue = 0;
            }else if(blue>1){
                blue = 1;
            }
            return 0xff000000 |
                    ((int) (red   * 255.0f + 0.5f) << 16) |
                    ((int) (green * 255.0f + 0.5f) <<  8) |
                    (int) (blue  * 255.0f + 0.5f);
        }

        /**
         * 返回以指定颜色长度编码的红色组件。返回值的范围取决于与指定颜色关联的颜色空间。可以通过调用{@link #colorSpace(long)}来查询颜色空间。
         * @param color 要提取其红色通道的长颜色
         * @return 具有由指定颜色的颜色空间定义的范围的浮点值
         *
         * @see #colorSpace(long)
         * @see #green(long)
         * @see #blue(long)
         * @see #alpha(long)
         */
        public static float red(@ColorLong long color) {
            if ((color & 0x3fL) == 0L) return ((color >> 48) & 0xff) / 255.0f;
            return toFloat((short) ((color >> 48) & 0xffff));
        }

        /**
         * 返回以指定颜色长度编码的绿色组件。返回值的范围取决于与指定颜色关联的颜色空间。可以通过调用{@link #colorSpace(long)}来查询颜色空间。
         * @param color 要提取其绿色通道的长颜色
         * @return 具有由指定颜色的颜色空间定义的范围的浮点值
         * @see #colorSpace(long)
         * @see #red(long)
         * @see #blue(long)
         * @see #alpha(long)
         */
        public static float green(@ColorLong long color) {
            if ((color & 0x3fL) == 0L) return ((color >> 40) & 0xff) / 255.0f;
            return toFloat((short) ((color >> 32) & 0xffff));
        }
        /**
         * 返回以指定颜色长度编码的蓝色组件。返回值的范围取决于与指定颜色关联的颜色空间。可以通过调用{@link #colorSpace(long)}来查询颜色空间。
         *
         * @param color 要提取其蓝色通道的长颜色
         * @return 具有由指定颜色的颜色空间定义的范围的浮点值
         * @see #colorSpace(long)
         * @see #red(long)
         * @see #green(long)
         * @see #alpha(long)
         */
        public static float blue(@ColorLong long color) {
            if ((color & 0x3fL) == 0L) return ((color >> 32) & 0xff) / 255.0f;
            return  toFloat((short) ((color >> 16) & 0xffff));
        }

        /**
         * 返回以指定颜色长度编码的alpha组件。返回的值始终在范围（[0..1]）内。
         * @param color 要提取其alpha通道的长颜色
         * @return 范围为（[0..1]）的浮点值
         * @see #colorSpace(long)
         * @see #red(long)
         * @see #green(long)
         * @see #blue(long)
         */
        public static float alpha(@ColorLong long color) {
           // int c=Color.toArgb(color);
            if ((color & 0x3fL) == 0L) return ((color >> 56) & 0xff) / 255.0f;
            return ((color >> 6) & 0x3ff) / 1023.0f;
        }

        /**
         * 将指定的长颜色转换为ARGB整型颜色。整型颜色始终位于{@link color space.Named#SRGB SRGB}颜色空间中。这意味着如果需要，将应用颜色空间转换。
         * @param color  要转换的长颜色
         * @return sRGB颜色空间中的ARGB颜色
         */
        @ColorInt
        public static int toArgb(@ColorLong long color) {
            if ((color & 0x3fL) == 0L) return (int) (color >> 32);
            float r = red(color);
            float g = green(color);
            float b = blue(color);
            float a = alpha(color);
            return ((int) (a * 255.0f + 0.5f) << 24) |
                    ((int) (r   * 255.0f + 0.5f) << 16) |
                    ((int) (g * 255.0f + 0.5f) <<  8) |
                    (int) (b  * 255.0f + 0.5f);
        }
        /**
         * 按指定透明度重新输出
         * @param color 需要转换的颜色
         * @param alpha 透明度
         * @return 返回指定透明度的新颜色
         */
        public static int toColor(int color,float alpha){
            float red=Color.red(color)/255.0f;
            float green=Color.green(color)/255.0f;
            float blue=Color.blue(color)/255.0f;
            return argb(alpha,red,green ,blue );
        }
        /**
         * 按指定透明度重新输出
         * @param color 需要转换的颜色
         * @param alpha 透明度0-255
         * @return 返回指定透明度的新颜色
         */
        public static int toColor(int color,int alpha){
            return argb(alpha,red(color),green(color),blue(color));
        }
        /**
         * <p>将指定的半精度浮点值转换为单精度浮点值。
         * @param h 要与此{@code half}对象表示的半精度值进行比较的半精度浮点值
         * @return 如果{@code x}在数值上等于{@code y}，则为{@code 0}；如果{@code x}在数值上小于{@code y}，则为小于{@code 0}；如果{@code x}在数值上大于{@code y}，则为大于{@code 0}
         */
        public static float toFloat( short h) {
            int bits = h & 0xffff;
            int s = bits & 0x8000;
            int e = (bits >>> 10) & 0x1f;
            int m = (bits                        ) & 0x3ff;

            int outE = 0;
            int outM = 0;

            if (e == 0) { // Denormal or 0
                if (m != 0) {
                    // Convert denorm fp16 into normalized fp32
                    float o = Float.intBitsToFloat((126 << 23) + m);
                    o -= Float.intBitsToFloat((126 << 23));
                    return s == 0 ? o : -o;
                }
            } else {
                outM = m << 13;
                if (e == 0x1f) { // Infinite or NaN
                    outE = 0xff;
                    if (outM != 0) { // SNaNs are quieted
                        outM |= 0x400000;
                    }
                } else {
                    outE = e - 15 + 127;
                }
            }
            int out = (s << 16) | (outE << 23) | outM;
            return Float.intBitsToFloat(out);
        }
    }
}